package com.pipayshop.service.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.pipayshop.entity.TradinPost;
import com.pipayshop.entity.UserInfo;
import com.pipayshop.entity.vo.TraditionDetailVO;
import com.pipayshop.entity.vo.TraditionListVO;
import com.pipayshop.exception.BusinessException;

import com.pipayshop.mapper.ImageMapper;
import com.pipayshop.mapper.TradinPostMapper;
import com.pipayshop.service.TradinPostService;
import com.pipayshop.service.UserAccountInfoService;
import com.pipayshop.service.UserInfoService;
import com.pipayshop.utils.StringUtil;
import com.pipayshop.utils.TokenUtil;
import io.jsonwebtoken.Claims;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;


import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author wzx
 * @since 2023-09-09
 */
@Service
public class TradinPostServiceImpl extends ServiceImpl<TradinPostMapper, TradinPost> implements TradinPostService {

    @Resource
    private TradinPostMapper tradinPostMapper;
    @Resource
    private ImageMapper imageMapper;
    @Resource
    private UserAccountInfoService accountInfoService;
    @Resource
    private UserInfoService userInfoService;


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean publishTradition(String token) {
        // 解析token
        Claims dataFromToken = TokenUtil.getDataFromToken(token);
        String publisherId = dataFromToken.get("publisherId", String.class);
        Integer typeId = dataFromToken.get("typeId", Integer.class);
        String content = dataFromToken.get("content", String.class);
        if (StringUtils.isBlank(publisherId) || StringUtils.isBlank(content) || typeId == null) {
            throw new BusinessException("invalid_parameter");
        }
        BigDecimal pointBalance = BigDecimal.valueOf(Double.parseDouble(dataFromToken.get("pointBalance", String.class)));
        BigDecimal piBalance = BigDecimal.valueOf(Double.parseDouble(dataFromToken.get("piBalance", String.class)));
        if (pointBalance.compareTo(BigDecimal.ZERO) <= 0 || piBalance.compareTo(BigDecimal.ZERO) <= 0) {
            throw new BusinessException("数据错误");
        }
        String tradinId = StringUtil.generateShortId();
        int insert = 0;

        // 发布者换积分
        if (typeId == 0) {
            insert += tradinPostMapper.insert(new TradinPost(tradinId, publisherId, typeId, content, pointBalance, piBalance, null, StringUtil.generateShortId(), 0, new Date(), new Date()));
            if (insert < 1) {
                throw new BusinessException("数据插入失败");
            }
            // 发布者换pi币
        } else if (typeId == 1) {
            //冻结积分
            accountInfoService.freezePoints(publisherId, pointBalance);
            String piAddress = dataFromToken.get("piAddress", String.class);
            if (piAddress.isEmpty()) {
                throw new BusinessException("pi地址不能为空");
            }
            insert += tradinPostMapper.insert(new TradinPost(tradinId, publisherId, typeId, content, pointBalance, piBalance, piAddress));
            if (insert < 1) {
                throw new BusinessException("数据插入失败");
            }
        }
        return true;
    }


    @Override
    public TraditionDetailVO selectTraditionDetail(String tradinId) throws InterruptedException {
        if (StringUtils.isBlank(tradinId)) {
            throw new BusinessException("invalid_parameter");
        }
        // 获取锁（可重入），指定锁的名称
//        RLock lock = redissonClient.getLock(tradinId);
        // 尝试获取锁，参数分别是：获取锁的最大等待时间（期间会重试），锁自动释放时间，时间单位
//        boolean isLock = lock.tryLock(1, 10, TimeUnit.SECONDS);
        TraditionDetailVO traditionDetailVO;
        // 判断释放获取成功
//        if(isLock){
//            try {
        //执行业务需求
//                TradinPost tradinPost = tradinPostMapper.selectOne(new QueryWrapper<TradinPost>()
//                                                                    .eq("tradin_id", tradinId)
//                                                                    .select("status","tradin_id","id"));
//                // 判断是否有人查看
//                if (tradinPost.getStatus() != 0){
//                    // 有人在查看
//                    return null;
//                }
        // 上锁让其他人不能访问 更新状态，
//                tradinPost.setStatus(1);
//                int updateById = tradinPostMapper.updateById(tradinPost);
//                if (updateById < 1){
//                    throw new BusinessException("更新状态失败");
//                }
        // 返回数据
        traditionDetailVO = tradinPostMapper.selectTraditionDetail(tradinId);
        if (traditionDetailVO == null) {
            throw new BusinessException("查询失败");
        }
        if (traditionDetailVO.getUserImage() != null) {
            traditionDetailVO.setUserImage(imageMapper.selectPath(traditionDetailVO.getUserImage()));
        }
//            }finally {
//                // 释放锁
//                lock.unlock();
//            }
//        }
        return traditionDetailVO;
    }


    @Override
    public List<TraditionListVO> selectTradinPostByUid(String token) {
        // 解析token
        Claims dataFromToken = TokenUtil.getDataFromToken(token);
        String userId = dataFromToken.get("userId", String.class);
        if (StringUtils.isBlank(userId)) {
            throw new BusinessException("invalid_parameter");
        }
        return tradinPostMapper.selectTradinPostByUid(userId);
    }

    @Override
    public List<TraditionListVO> selectTraditionListByPiName(Integer typeId, Integer page, Integer limit, String piName) {
        return tradinPostMapper.selectTraditionListByPiName(typeId, (page - 1) * limit, limit, piName);
    }

    @Override
    @Transactional
    public void cancelTradition(String tradinId, String piName) {
        if (StringUtils.isBlank(tradinId) || StringUtils.isBlank(piName)) {
            throw new BusinessException("invalid_parameter");
        }
        // 查看交易状态
        TradinPost tradition = this.getOne(new LambdaQueryWrapper<TradinPost>()
                .eq(TradinPost::getTradinId, tradinId));
        if (tradition == null) {
            throw new BusinessException("transaction_not_exist");
        }
        if (tradition.getStatus() == 4) {
            throw new BusinessException("transaction_cancelled");
        }
        if (tradition.getStatus() == 3) {
            throw new BusinessException("transaction_completed");
        }
        if (tradition.getStatus() == 2) {
            throw new BusinessException("transaction_in_progress");
        }
        try {
            // 修改交易状态
            update(null, new UpdateWrapper<TradinPost>()
                    .eq("tradin_id", tradinId)
                    .set("status", 4)
                    .set("update_time", new Date()));

            if (tradition.getTypeId() == 1) {
                UserInfo userInfo = userInfoService.getOne(new QueryWrapper<UserInfo>()
                        .eq("pi_name", piName));
                // 积分换pi币返还积分
                accountInfoService.unfreezePoints(userInfo.getUid(), tradition.getPointBalance());
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new BusinessException("transaction_cancellation_failed");
        }
    }
}
